#ifndef PAGING_H_
#define PAGING_H_

#include <types.h>

#define PG_CR0_PG (1 << 31)
#define PG_CR4_PSE (1 << 4)
#define PG_CR4_PAE (1 << 5)

#define PG_PDE_P 0
#define PG_PDE_RW 1
#define PG_PDE_US 2
#define PG_PDE_PWT 3
#define PG_PDE_PCD 4
#define PG_PDE_A 5
#define PG_PTE_D 6
#define PG_PDE4MB_D 6
#define PG_PDE_PS 7
#define PG_PTE_PAT 7
#define PG_PDE_GLOBAL 8
#define PG_PDE4MB_PAT 12

//#define _pa2va(addr, pd) ((((dword*)(pd[((addr) & 0xFFC00000) >> 22])[((addr) & 0x003FF000) >> 12]) & ~0xFFF) | ((addr) & 0xFFF))
#define _pa2va(addr, pd) pg_pa2va(addr, pd)

// user defined bit fields
#define PG_PDE_FULL 9

#define PG_ERR_NOALLOC 1

int init_paging(void);
dword pg_pagetable_alloc(byte rw, byte us, byte wtr, byte pcd, byte g);
dword pg_pte_alloc(dword addr, byte rw, byte us, byte wtr, byte pcd, byte g);
void pg_get_structs_from_addr(void *addr, dword *pde, dword *pte);
void * pg_map_frame(void *frame, dword *pd);
dword * pg_create_address_space(void);
dword pg_pa2va(void *addr, dword *pd);

#endif /*PAGING_H_*/
